#ifndef TestQueryEvaluatorWithPKB_h
#define TestQueryEvaluatorWithPKB_h
#include "DesignExtractor.h"
#include <cppunit/extensions/HelperMacros.h>

class QueryEvaluatorWithPKBTest : public CPPUNIT_NS::TestFixture {
	private:
		#define MAX_CONTAINER 20
		CPPUNIT_TEST_SUITE( QueryEvaluatorWithPKBTest );
		/*
		CPPUNIT_TEST( testConstructor );
		CPPUNIT_TEST( testEvaluateFollows );
		CPPUNIT_TEST( testEvaluateFollowsStar );
		CPPUNIT_TEST( testEvaluateParent );
		CPPUNIT_TEST( testEvaluateParentStar );
		CPPUNIT_TEST( testEvaluateModifies );
		CPPUNIT_TEST( testEvaluateModifiesProcedure );
		CPPUNIT_TEST( testEvaluateUses );
		CPPUNIT_TEST( testEvaluateUsesProcedure );
		CPPUNIT_TEST( testEvaluateCalls );
		CPPUNIT_TEST( testEvaluateCallsStar );
		CPPUNIT_TEST( testEvaluateNext );
		*/
		CPPUNIT_TEST( testEvaluateNextStar );

		/*
		CPPUNIT_TEST( testEvaluatePatternAssign );
		CPPUNIT_TEST( testEvaluateSuchThatPatternAssign );
		CPPUNIT_TEST( testEvaluateWithClauses );
		CPPUNIT_TEST( testEvaluateBooleanQuery );
		CPPUNIT_TEST( testEvaluateToughQuery );
		CPPUNIT_TEST( testEvaluateTuples );
		*/
		CPPUNIT_TEST_SUITE_END();

	public:
		void setUp();
		void tearDown();
		// Sets up a PKB with the following SIMPLE source code:
		// Procedure MyProc {
		//1.	x = 2;
		//2.	y = x;
		//3.	while x {
		//4.		x = x - 1;
		//5.		y = y + x;
		//6.		while y {
		//7.			z = y - 1;
		//			}
		//		}
		//8.	y = 5;
		// }
		PKB setUpPkb();
		// Sets up a PKB with the following SIMPLE source code:
		// Procedure MyProc {
		//1.	x = 2;
		//2.	y = x;
		//3.	while x {
		//4.		x = x - 1;
		//5.		y = y + x;
		//6.		while y {
		//7.			z = y - 1;
		//			}
		//		}
		//8.	y = 5;
		//9.	while x {
		//10.		while y {
		//11.			call YourProc;
		//			}
		//		}
		// }
		//
		// Procedure YourProc {
		//12.	a = 9;
		//13.	b = b + c;
		//14.	call YourOtherProc;
		// }
		//
		// Procedure YourOtherProc {
		//15.	d = d + 15;
		//16.	while d {
		//17.		d = e;
		//		}
		// }
		PKB setUpPkbWithMultipleProcedures();
		// Sets up a PKB with the following SIMPLE source code:
		// Procedure MyProc {
		//1.	x = 2;
		//2.	y = x;
		//3.	while x {
		//4.		x = x - 1;
		//5.		y = y + x;
		//6.		while y {
		//7.			z = y - 1;
		//			}
		//		}
		//8.	y = 5;
		//9.	while x {
		//10.		while y {
		//11.			call YourProc;
		//			}
		//		}
		// }
		//
		// Procedure YourProc {
		//12.	a = 9;
		//13.	b = b + c;
		//14.	call YourOtherProc;
		// }
		//
		// Procedure YourOtherProc {
		//15.	d = d + 15;
		//16.	while d {
		//17.		d = e;
		//		}
		// }
		//
		// Procedure IfStmtProc {
		//18.	if d then {
		//19.		d = e;
		//20.		while d {
		//21.			d = e - 1 * 2;
		//			}
		//		} else {
		//22.		d = e;
		//23.		while d {
		//24.			d = e - 1 * 2;
		//			}
		//		}
		//25.	while d {
		//26.		if d then {
		//27.			d = e;
		//28.			while d {
		//29.				d = e - 1 * 2;
		//				}
		//			} else {
		//30.			d = e;
		//31.			while d {
		//32.				d = e - 1 * 2;
		//				}
		//			}
		//		}
		//	}
		PKB setUpPkbWithMultipleProceduresAndIfStmts();
		// Tests the constructor
		void testConstructor();
		// Tests the evaluateQuery function for FOLLOWS relationship
		void testEvaluateFollows();
		// Tests the evaluateQuery function for FOLLOWSTAR relationship
		void testEvaluateFollowsStar();
		// Tests the evaluateQuery function for PARENT relationship
		void testEvaluateParent();
		// Tests the evaluateQuery function for PARENTSTAR relationship
		void testEvaluateParentStar();
		// Tests the evaluateQuery function for MODIFIES_LINE relationship
		void testEvaluateModifies();
		// Tests the evaluateQuery function for MODIFIES_PROC relationship
		void testEvaluateModifiesProcedure();
		// Tests the evaluateQuery function for USES_LINE relationship
		void testEvaluateUses();
		// Tests the evaluateQuery function for USES_PROC relationship
		void testEvaluateUsesProcedure();
		// Tests the evaluateQuery function for CALLS relationship
		void testEvaluateCalls();
		// Tests the evaluateQuery function for CALLSSTAR relationship
		void testEvaluateCallsStar();
		// Tests the evaluateQuery function for NEXT relationship
		void testEvaluateNext();
		// Tests the evaluateQuery function for NEXTSTAR relationship
		void testEvaluateNextStar();
		// Tests the evaluateQuery function for PATTERNS!
		void testEvaluatePatternAssign();
		// Tests the evaluateQuery function for both such that and PATTERNS!
		void testEvaluateSuchThatPatternAssign();
		// Tests the evaluateQuery function for with-clauses
		void testEvaluateWithClauses();
		// Tests the evaluateQuery function when selecting BOOLEAN
		void testEvaluateBooleanQuery();
		// Tests the evaluateQuery function for mixed queries that are complex
		void testEvaluateToughQuery();
		// Tests the evaluateQuery function tuples querying
		void testEvaluateTuples();
		Type::Map::ParentMatrix prepareCommMatrixFromArray(int a[][MAX_CONTAINER], int index[], int size);
};
#endif